package mark.tom.gear.base.activity

import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.Resources
import android.os.Build
import android.os.Build.VERSION
import android.os.Bundle
import android.os.Process
import android.view.*
import androidx.annotation.CallSuper
import androidx.annotation.DrawableRes
import androidx.annotation.IntDef
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.appcompat.widget.Toolbar
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModelProvider
import com.hundsun.gmubase.widget.SystemBarSetting
import mark.tom.base.R
import mark.tom.gear.base.utils.SnackBarUtil
import mark.tom.gear.base.utils.SystemBarUtil
import java.lang.reflect.ParameterizedType

/**
 * @Description: Activity基类
 * @Author: ttmk110@163.com
 * @Package: mark.tom.gear.base.activity
 * @Date: 2021/1/19
 * @Copyright: 版权归 Mark 所有
 * <ModifyLog>
 * @ModifyContent:
 * @Author:
 * @Date:
 * </ModifyLog>
 */
abstract class BaseActivity<VM : AndroidViewModel> : AppCompatActivity() {

    // mExistTime为记录第一次按返回键的时间
    private var mExitTime: Long = 0
    // statusBar高度
    private var statusBarHeight = 0
    // ToolBar高度
    private var toolBarHeight = 0
    // ToolBar对象
    private lateinit var mToolBar: Toolbar
    // 返回键点击效果
    @BaseActivity.BackWayEnums
    private var backOperation: Int = BACK_WAY_CLICK
    // ViewModel
    protected lateinit var mViewModel: VM

    @CallSuper
    override fun onCreate(savedInstanceState: Bundle?) {
        // 设置是否有标题
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        // 强制竖屏
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        // 设置是否全屏
        if (isFullScreen()) {
            window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            )
        }
        super.onCreate(savedInstanceState)
        lateinit var contentView: View
        if (isToolBarInContent()) {
            // 添加根视图
            val mRootView = LinearLayoutCompat(this)
            mRootView.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            mRootView.orientation = LinearLayoutCompat.VERTICAL
            // 获取高度
            statusBarHeight = SystemBarUtil.getStatusBarHeight(resources)
            // 添加ToolBar视图
            mToolBar = layoutInflater.inflate(R.layout.include_toolbar, mRootView, false) as Toolbar
            setToolBar(mToolBar.findViewById(R.id.appToolBar))
            mRootView.addView(mToolBar)
            // 添加内容视图
            contentView = getLayoutView(layoutInflater, mRootView)
            mRootView.addView(contentView)
            // 设置当前的视图
            this.setContentView(mRootView)
        } else {
            val container: ViewGroup = window.decorView.findViewById(android.R.id.content)
            contentView = getLayoutView(layoutInflater, container)
            this.setContentView(contentView)
        }
        // 开启透明模式
        if (isTransparentMode()) {
            SystemBarSetting.setSystemBar(
                this,
                findViewById(android.R.id.content),
                R.color.statusBar_color_bg
            )
        }
        SystemBarUtil.setStatusTextColor(isUseDartTheme(), this)
        // 创建ViewModel对象
        mViewModel = createViewModel()
        onCreate(contentView, savedInstanceState)
    }

    @SuppressWarnings("unchecked")
    private fun createViewModel(): VM {
        // 这里获得到的是类的泛型的类型
        val parameterizedType = javaClass.genericSuperclass as ParameterizedType
        val actualTypeArguments = parameterizedType.actualTypeArguments
        val vmClass = actualTypeArguments[0] as Class<VM>
        return ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        )[vmClass]
    }

    /**
     * Description: 获取ToolBar对象
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/25 9:11
     */
    protected open fun getToolBar(): Toolbar? {
        return if (this::mToolBar.isInitialized) mToolBar else null
    }

    /**
     * Description: 是否全屏
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/19 13:33
     */
    protected open fun isFullScreen(): Boolean {
        return false
    }

    /**
     * Description: 是否沉浸式模式
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/19 13:33
     */
    protected open fun isTransparentMode(): Boolean {
        return true
    }

    /**
     * Description: 是否需要添加ToolBar
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/19 13:33
     */
    protected open fun isToolBarInContent(): Boolean {
        return true
    }

    /**
     * Description: 是否使用黑色主题
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/25 9:00
     */
    protected open fun isUseDartTheme(): Boolean {
        return false
    }

    /**
     * Description: 页面返回方式
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/19 13:33
     */
    protected open fun setBackAwayMode(@BackWayEnums backAwayEnum: Int) {
        backOperation = backAwayEnum
    }

    /**
     * Description: 获取当前页面布局
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/19 13:33
     */
    protected abstract fun getLayoutView(inflater: LayoutInflater, mRootView: ViewGroup): View

    /**
     * Description: Activity启动
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/2/8 1:31 下午
     */
    protected abstract fun onCreate(contentView: View, savedInstanceState: Bundle?)

    /**
     * Description: 设置ToolBar
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/25 9:01
     */
    protected open fun setToolBar(toolBar: Toolbar?) {
        setToolBar(toolBar, R.mipmap.icon_toolbar_back)
    }

    /**
     * Description: 设置ToolBar
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/25 9:01
     */
    protected open fun setToolBar(toolBar: Toolbar?, @DrawableRes navigationIconId: Int) {
        if (toolBar == null) {
            return
        }
        // 如果Android版本大于4.4则采用沉浸式,需要重设toolbar高度
        if (VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && statusBarHeight != 0) {
            val h = toolBar.layoutParams.height
            toolBarHeight = h + statusBarHeight
            toolBar.layoutParams.height = toolBarHeight
            val pB = toolBar.paddingBottom
            val pT = toolBar.paddingTop
            val pL = toolBar.paddingLeft
            val pR = toolBar.paddingRight
            toolBar.setPadding(pL, pT + statusBarHeight, pR, pB)
        } else {
            toolBarHeight = toolBar.layoutParams.height
        }
        // 设置左图标和其点击事件
        if (backOperation == BACK_WAY_CLICK || backOperation == BACK_WAY_CONFIRM) {
            // 设置ToolBar背景色
            try {
                toolBar.setNavigationIcon(navigationIconId)
            } catch (ex: Exception) {
                toolBar.setNavigationIcon(R.mipmap.icon_toolbar_back)
            }
        }
        toolBar.setNavigationOnClickListener(View.OnClickListener {
            // 处理返回事件
            doBackOperation()
        })
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
            // 处理返回事件
            doBackOperation()
            return true
        }
        return super.onKeyDown(keyCode, event)
    }

    /**
     * Description: 处理返回事件
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/19 13:42
     */
    private fun doBackOperation() {
        when (backOperation) {
            BACK_WAY_CLICK -> finish()
            BACK_WAY_CONFIRM -> backConfirmEvent()
            BACK_WAY_MINIMIZE -> {
                // 最小化应用
                val intent = Intent(Intent.ACTION_MAIN)
                intent.addCategory(Intent.CATEGORY_HOME)
                intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
                startActivity(intent)
            }
            BACK_WAY_DOUBLE -> {
                // 按两下返回键退出应用
                if (System.currentTimeMillis() - mExitTime > 1.5 * 1000) {
                    // 提示再按一次退出提示
                    SnackBarUtil.showSnackBar(this, R.string.app_exit_warn)
                    mExitTime = System.currentTimeMillis()
                } else {
                    Process.killProcess(Process.myPid())
                }
            }
        }
    }

    /**
     * Description: 返回确认事件(需要重写该方法)
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/1/25 9:13
     */
    protected open fun backConfirmEvent() {
        // 重写此方法，以满足不同的需求
    }

    /**
     * Description: 重写获取Resource方法 强制字体不允许更改
     * Copyright: Copyright (c) 2021
     * Project: Gear
     * Author: ttmk110@163.com
     * Date: 2021/2/8 1:32 下午
     */
    override fun getResources(): Resources {
        val res = super.getResources()
        val configuration = res.configuration
        if (configuration.fontScale != 1.0f) {
            configuration.fontScale = 1.0f
            res.updateConfiguration(configuration, res.displayMetrics)
        }
        return res
    }

    companion object {
        const val BACK_WAY_DOUBLE = 0
        const val BACK_WAY_CLICK = 1
        const val BACK_WAY_CONFIRM = 2
        const val BACK_WAY_MINIMIZE = 3
    }

    @IntDef(value = [BACK_WAY_DOUBLE, BACK_WAY_CLICK, BACK_WAY_CONFIRM, BACK_WAY_MINIMIZE])
    @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
    private annotation class BackWayEnums

}